package com.yuncheng.oaApi.FlowService;


import cn.hutool.core.bean.BeanUtil;
import com.yuncheng.oaApi.vo.AgentVo;
import com.yuncheng.oaApi.vo.OaFlowVo;
import com.yuncheng.oaApi.vo.OaReturnVo;
import com.yuncheng.oaApi.vo.Result;
import com.yuncheng.spcyApi.service.ISpcyLogService;
import org.apache.commons.collections.CollectionUtils;
import com.yuncheng.oaApi.utils.GetUuIdUtils;;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.oaApi.busService.OaDbrService;
import com.yuncheng.oaApi.busService.OaFlowNodeDbrService;
import com.yuncheng.oaApi.busService.OaFlowNodeService;
import com.yuncheng.oaApi.constant.OaCommonFlowConstant;
import com.yuncheng.oaApi.constant.OaFlowNodeConstant;

import com.yuncheng.oaApi.constant.OaFlowConstant;
import com.yuncheng.oaApi.constant.OaSpcyJcyFybxdConstant;
import com.yuncheng.oaApi.entity.*;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.oaApi.service.*;
import com.yuncheng.oaApi.service.impl.OaYcSysUserServiceImpl;
import com.yuncheng.spcyApi.utils.DateConvert;
import com.yuncheng.utils.ThreadContextHelper;
import com.yuncheng.vo.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import utils.DateConversionUtils;
import utils.LogUtils;
import utils.ObjectToMapUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

@Component(value = "NewBxTssxsqFlowService")
public class NewBxTssxsqFlowService {
    private static final Logger log = LoggerFactory.getLogger(NewBxTssxsqFlowService.class);

    @Resource
    private IOaSpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private OaYcSysUserServiceImpl ycSysUserService;

    @Resource
    @Lazy
    private ISpcyLogService spcyLogService;

    @Resource
    @Lazy
    private IOaSysTzMessageService sysTzMessageService;

    @Resource
    @Lazy
    private IOaSysFlowNodeService sysFlowNodeService;

    @Resource
    @Lazy
    private OaFlowNodeService oaFlowNodeService;

    @Resource
    @Lazy
    private OaFlowNodeDbrService oaFlowNodeDbrService;

    @Resource
    @Lazy
    private IOaSysFlowTempleService sysFlowTempleService;

    @Resource
    @Lazy
    private IOaSysJobService sysJobService;

    @Resource
    @Lazy
    private IOaSpcyJcyFybxdtssxsqService spcyFybxdtssxsqService;

    @Resource
    @Lazy
    private IOaSpcyJcyFybxdService spcyJcyFybxdService;

    @Resource
    @Lazy
    private INkRsCcspService nkRsCcspService;

    @Resource
    @Lazy
    private OaDbrService oaDbrService;




    public Result handleFlow(OaFlowVo oaFlowVo, OaJobEntity nowJob, String jobId, String oaid, String submitType, String opinion) {

        // 当前流程任务
        if (StringUtils.isNotBlank(jobId)) {
            nowJob = spcySqsxJobService.getById(jobId);
        }

        if (nowJob == null) {
            return Result.error("当前流程任务不存在，请重试");
        }
        if (StringUtils.isBlank(oaid)) {
            oaid = nowJob.getFpid();
        }

        if (StringUtils.isBlank(oaid)) {
            throw new BusinessException("参数丢失，请联系管理员");
        }


        // 提交按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            if (nowJob == null) {
                return Result.error("当前流程任务不存在");
            }
        }
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        if (currentUser == null) {
            return Result.error("登录已失效，请重新登录");
        }

        //申请
        if (nowJob.getFhjmc().equals(OaFlowConstant.TSSXSQ_SQ)) {

            //经办人审核
        }else if (nowJob.getFhjmc().equals(OaFlowConstant.TSSXSQ_JBR)){
            //经办人审核完 下一环节审批人为





            OaSpcyJcyFybxdtssxsq tssxq =  spcyFybxdtssxsqService.getById(oaid);

            if (tssxq.getFsffqlc().equals(OaCommonFlowConstant.SFFQLC_NO)){
                tssxq.setFsffqlc(OaCommonFlowConstant.SFFQLC_YES);
            }


            String name = currentUser.getName();
            String id = currentUser.getId();
            tssxq.setFsqzt("已申请");
            tssxq.setFjbrxm(name);
            tssxq.setFjbryjsj(DateConversionUtils.DateToDays(new Date()));
            tssxq.setFjbrid(id);
            spcyFybxdtssxsqService.updateById(tssxq);
        }



        // 流程环节处理
        Result httpResult = handleNodeName(oaFlowVo, submitType, nowJob, oaid, opinion);
        if (!httpResult.isSuccess()) {
            return httpResult;
        }

        //最后一步状态标注流程结束
        /**
         * @Author: lhb
         * @Description :  是最后一步流程 且是 提交 才会判断为流程结束
         * @DateTime:
         * @Params:
         */
        String fnodeid = nowJob.getFnodeid();
        boolean endNode = sysFlowNodeService.endNode(fnodeid);
        if(endNode && submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            //当前流程id
            OaSpcyJcyFybxdtssxsq tssxq =  spcyFybxdtssxsqService.getById(oaid);

            tssxq.setFzxldid(currentUser.getId());
            tssxq.setFzxldyjr(currentUser.getName());
            tssxq.setFlczt(OaCommonFlowConstant.FLOW_LCJS);
            tssxq.setFzxldyjsj(DateConversionUtils.DateToDays(new Date()));
            spcyFybxdtssxsqService.updateById(tssxq);

            //更新完成后在信息通知表里插入一条消息 表示未读
            sysTzMessageService.endMessage(oaid,false,true,false);



        }
        return Result.ok("操作成功");

    }

    public Result handleNodeName(OaFlowVo oaFlowVo, String submitType, OaJobEntity job, String oaId, String opinion){
        HashMap<String, Object> map = oaFlowVo.getMap();
        String dbrid = oaFlowVo.getDbrid();// 下环节待办人
        String smgflag = oaFlowVo.getSmgflag(); // 短信发送标志
        boolean isSubmit = true; // 是否提交流程
        Result res = null;

        // 保存按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SAVE)){
            updateSqsxJbxx(map,oaId,job);
        }

        // 提交按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)){
            updateSqsxJbxx(map,oaId,job);

            // 流程任务id
            String jobId = "";
            if (job != null){
                jobId = job.getId();
            }

            // 提交流程任务,待办人是否为空，指定待办人
            if (isSubmit) {
                if (StringUtils.isBlank(dbrid)) {
                    // 提交-流程任务
                    res = this.passJob(oaId, jobId, opinion, "", "");
                } else {
                    // 提交-流程任务
                    res = this.passJob(oaId, jobId, opinion, "", dbrid);
                }
            }
            if (!res.isSuccess()){
                return res;
            }else {
                OaJobEntity nowJob = (OaJobEntity)res.getResult();
                // 接收返回的流程任务，如果返回的流程任务id不相等，发送短信
                if (nowJob != null && !jobId.equals(nowJob.getId()) && StringUtils.isNotBlank(smgflag) && smgflag.equals("是")){

                }
            }
        }

        return Result.ok("提交成功");
    }


    public Result updateSqsxJbxx(HashMap<String,Object> map, String oaid, OaJobEntity job){
        OaSpcyJcyFybxdtssxsq oldBasic = spcyFybxdtssxsqService.getById(oaid);
        if (oldBasic == null){
            return Result.error("当前申请事项【"+oaid+"】不存在，请重试");
        }
        OaSpcyJcyFybxdtssxsq basicUpdate = null;
        basicUpdate = oldBasic;

        // 修改
        ConvertUtils.register(new DateConvert(), Date.class);
        try {
            BeanUtils.populate(basicUpdate,map);
            spcyFybxdtssxsqService.updateById(basicUpdate);
        } catch (IllegalAccessException e) {
            log.error("出错-保存申请事项【非法访问异常】,{}",e.getMessage());
        } catch (InvocationTargetException e) {
            log.error("出错-保存申请事项【调用TargetException】,{}",e.getMessage());
        }

        String logContent = "基本信息修改: ";
        Map<String, Object> basicMap = ObjectToMapUtils.objectToMap(oldBasic);
        logContent += LogUtils.BeanModifyMsg(basicUpdate,basicMap);

        if (job == null) {
            spcyLogService.addLogs("null", logContent, oaid, OaCommonFlowConstant.LOGS_SYS_TYPE_XG, OaCommonFlowConstant.LOGS_SYS_TYPE_XG);
        }else {
            spcyLogService.addLogs(job.getFhjmc(), logContent, oaid, OaCommonFlowConstant.LOGS_SYS_TYPE_XG, OaCommonFlowConstant.LOGS_SYS_TYPE_XG);
        }

        return Result.ok("保存成功");
    }

    public Map getJobConcernByJobId(String jobid) {
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        Map map = new HashMap();

        // 当前流转记录
        OaJobEntity job = spcySqsxJobService.getById(jobid);
        if (job == null){
            log.error("当前流程任务id为【{}】的流转记录不存在",jobid);
            return map;
        }
        String oaid = job.getFpid();
        if (org.apache.commons.lang3.StringUtils.isBlank(oaid)){
            log.error("当前流程任务id为【{}】的流转记录中的申请事项id为空",jobid);
            return map;
        }
        // oaid事项基本信息
        OaSpcyJcyFybxdtssxsq sqsxBasic = spcyFybxdtssxsqService.getById(oaid);

        // 流程任务流传记录
        List<OaJobEntity> jobList = this.getJobListByOaId(oaid);
        String nextNode="";
        String nextNodeId="";

        String fnodeid = job.getFnodeid();
        //判断当前是否是最后一个节点 如果是 返回当前查询
        if (sysFlowNodeService.endNode(fnodeid)){
            List<OaSysFlowNode> nowNode = sysFlowNodeService.getNowNode(fnodeid);
            nextNode = nowNode.get(0).getFjdmc();
            nextNodeId = nowNode.get(0).getId();
        }else {
            List<OaSysFlowNode> nextNode1 = sysFlowNodeService.getNextNode(fnodeid);
            nextNode = nextNode1.get(0).getFjdmc();
            nextNodeId = nextNode1.get(0).getId();
        }
        // 获取下环节待办人
        Map nodeDbrids = oaFlowNodeService.getNodeDbrids(nextNodeId,jobid);

        List<AgentVo> dbrListByMap = oaFlowNodeDbrService.getDbrListByMap(nodeDbrids);

        map.put("sqsx",sqsxBasic); // 申请事项基本信息
        map.put("job",job); // 当前流转记录
        map.put("jobHistoryList",jobList); // 流程任务流传记录
        map.put("nextNodeDbrList",dbrListByMap); // 下环节待办人list
        map.put("nextNode",nextNode);

        return map;
    }
    /**
     * 获取oa-流转记录
     */
    public List<OaJobEntity> getJobListByOaId(String oaid) {

        String flcmbbm = OaFlowConstant.BXD_TSSXSQ;

        List<OaSysFlowTemple> list = sysFlowTempleService.list(new LambdaQueryWrapper<OaSysFlowTemple>().eq(OaSysFlowTemple::getFlcbm, flcmbbm));
        String flcmc = list.get(0).getFlcmc();
        LambdaQueryWrapper<OaJobEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(OaJobEntity::getFlcmc, flcmc);
        queryWrapper.eq(OaJobEntity::getFpid, oaid);
        queryWrapper.orderByAsc(OaJobEntity::getCreateTime);
        queryWrapper.orderByAsc(OaJobEntity::getFfssj);
        List<OaJobEntity> jobList = spcySqsxJobService.list(queryWrapper);
        return jobList;
    }


    /**
     *
     * @param lcmbCode 流程模板编码
     * @param oaid 业务id
     * @param currentUser 当前登陆用户
     * @return
     */
    public Result createProcess(String lcmbCode, String oaid, CurrentUserVo currentUser){

        //获取流程模板的第一个环节
        OaSysFlowTemple code = sysFlowNodeService.getCode(lcmbCode);

        List<OaSysFlowNode> node = sysFlowNodeService.getFirstNode(code.getId());

        List<OaJobEntity> list = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>()
                .eq(OaJobEntity::getFpid, oaid)
                .eq(OaJobEntity::getFhjmc, node.get(0).getFjdmc())
                .eq(OaJobEntity::getFlcmc,code.getFlcmc())
        );
        if(list.size()>0){
            List<String> ids = list.stream().map(OaJobEntity::getId).collect(Collectors.toList());
            spcySqsxJobService.removeBatchByIds(ids);
        }
        //只创建一次
        return this.createJob(lcmbCode,oaid,"",node.get(0),null,null,currentUser);
    }

    /**
     * 创建流程
     * @param lcmbCode 流程编码code
     * @param pid 业务id
     * @param dbrId 待办人id
     * @param nowNode 当前节点对象
     * @param nowJob 当前流程对象
     * @param nextNodeId 下一环节id
     * @param currentUser 当前登陆人
     * @return
     */
    public Result createJob(String lcmbCode, String pid, String dbrId, OaSysFlowNode nowNode, OaJobEntity nowJob, String nextNodeId, CurrentUserVo currentUser){
        String jobId = "";
        //如果  nextNodeId 不为空 则nowNode 直接等于传过来的nextNodeId 否则在判断 nowJob 为不为空
        if (StringUtils.isNotBlank(nextNodeId)){
            nowNode = sysFlowNodeService.getById(nextNodeId);
            if (nowJob != null){
                jobId = nowJob.getId();
            }
        } else
            //如果nowJob 不为空
            if (nowJob != null) {
                String fnodeid1 = nowJob.getFnodeid();
                jobId = nowJob.getId();
                List<OaSysFlowNode> nextNode = sysFlowNodeService.getNextNode(fnodeid1);
                if (nextNode == null) {
                    throw new BusinessException("");
                }
                if (nextNode.size() > 1) {
                    if (StringUtils.isBlank(nextNodeId)) {
                        throw new BusinessException("请选择提交环节");
                    } else {
                        nowNode = sysFlowNodeService.getById(nextNodeId);
                    }
                } else {
                    nowNode = nextNode.get(0);
                }
            }else {
                if (nowNode == null) {
                    throw new BusinessException("");
                }

            }
        String fnodeid = "";
        fnodeid = nowNode.getId();

        String fblfs = nowNode.getFblfs();
        String fjdmc = nowNode.getFjdmc();
        Integer fsfcjdpzhq = nowNode.getFsfcjdpzhq();

        String lcmc = sysFlowNodeService.getCode(lcmbCode).getFlcmc();

        OaJobEntity job = new OaJobEntity();
        job.setId(GetUuIdUtils.generateUuid());
        job.setFpid(pid);
        job.setFblfs(fblfs);
        job.setFhjmc(fjdmc);
        job.setFywlx(OaFlowConstant.OA);
        job.setFblzt(OaCommonFlowConstant.BLZT_DB);
        if(nowJob == null){
            job.setFsyhjid("");
        }else {
            job.setFsyhjid(nowJob.getId());
        }

        job.setFlcmc(lcmc);
        job.setFnodeid(fnodeid);
        if(currentUser != null) {
            job.setFfsrid(currentUser.getId());
            job.setFfsrmc(currentUser.getName());
        }
        job.setFfssj(new Date());
        //待办人和原待办人
        if (StringUtils.isNotBlank(dbrId)){
            job.setFdbrid(dbrId);
            job.setFdbr(oaFlowNodeDbrService.getDbrNameById(dbrId));
            job.setFydbr(oaFlowNodeDbrService.getDbrNameById(dbrId));
            job.setFydbrid(dbrId);
            spcySqsxJobService.save(job);
            return Result.ok(job);
        }

        OaSpcyJcyFybxdtssxsq fybxdtssxsq = spcyFybxdtssxsqService.getById(pid);

        int sqje = 0;
        if (StringUtils.isNotBlank(fybxdtssxsq.getFsqje())){
             sqje = Integer.parseInt(fybxdtssxsq.getFsqje());
        }else {
            sqje = 0;
        }


        OaSysFlowNode oaSysFlowNode = sysFlowNodeService.getById(fnodeid);
        String fjdmc1 = oaSysFlowNode.getFjdmc();
        if (StringUtils.isNotBlank(fybxdtssxsq.getFsfjcysq()) && fybxdtssxsq.getFsfjcysq().equals(OaCommonFlowConstant.SFFQLC_YES)
            && fjdmc1.equals(OaFlowConstant.TSSXSQ_JBR)){
            //如果是否为检查员申请不为空并且为是 ，并且是第二个环节
            OaSpcyJcyFybxd oaSpcyJcyFybxd = spcyJcyFybxdService.getById(fybxdtssxsq.getFbxdid());
            job.setFdbr(oaSpcyJcyFybxd.getFjbr());
            job.setFdbrid(oaSpcyJcyFybxd.getFjbrid());
            job.setFydbr(oaSpcyJcyFybxd.getFjbr());
            job.setFydbrid(oaSpcyJcyFybxd.getFjbrid());
            spcySqsxJobService.save(job);
            return Result.ok(job);
        } else if (fjdmc1.equals(OaFlowConstant.TSSXSQ_ZXZR) && fybxdtssxsq.getFsqlx().equals(OaSpcyJcyFybxdConstant.FYBXD_TSSXSQ_SQLX_WXF)
                    && sqje < 2000) {
            //如果是午休房 并且申请金额 在2000以下 那么 待办人是 经办人的分管领导
            String fsqks = fybxdtssxsq.getFsqks();
            Map ksFgldByDeptName = oaDbrService.getKsFgldByDeptName(fsqks);
            String dbr = ksFgldByDeptName.get("dbr").toString();
            String dbrId1 = ksFgldByDeptName.get("dbrId").toString();
            job.setFdbr(dbr);
            job.setFdbrid(dbrId1);
            job.setFydbr(dbr);
            job.setFydbrid(dbrId1);
            spcySqsxJobService.save(job);
            return Result.ok(job);

        } else if (fsfcjdpzhq.equals(OaFlowNodeConstant.SFZD_YES)){
            Map nodeDbrids = getNodeDbrids(fnodeid,jobId);
            dbrId = nodeDbrids.get("dbrId").toString();
            String dbr = nodeDbrids.get("dbr").toString();
            job.setFdbr(dbr);
            job.setFdbrid(dbrId);
            job.setFydbr(dbr);
            job.setFydbrid(dbrId);
            spcySqsxJobService.save(job);
            return Result.ok(job);
        }else{
            String dbrName = oaFlowNodeDbrService.getDbrNameById(dbrId);
            job.setFdbr(dbrName);
            job.setFdbrid(dbrId);
            job.setFydbr(dbrName);
            job.setFydbrid(dbrId);
            spcySqsxJobService.save(job);
            return Result.ok(job);
        }

    }


    /**
     *  提交环节待办记录 并创建下一环节待办
     *
     * @param oaId 业务id
     * @param jobId 流程id
     * @param opinion 意见
     * @param nextNodeId 下一节点id
     * @param nextNodeDbrIds 下一节点待办人
     * @return
     */
    public Result passJob(String oaId, String jobId, String opinion,String nextNodeId,String nextNodeDbrIds){
        //处理业务表的逻辑
        String lcmbCode = "";

        lcmbCode = OaFlowConstant.BXD_TSSXSQ;
        Result httpResult = passJob(lcmbCode, oaId, jobId, opinion, nextNodeId, nextNodeDbrIds,true);
        return httpResult;
    }

    /**
     *
     * @param nowNodeid 当前节点id
     * @param jobId 当前流程id
     * @return
     * 获取环节待办人
     */
    public Map getNodeDbrids(String nowNodeid,String jobId){
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        OaSysFlowNode oaSysFlowNode = sysFlowNodeService.getById(nowNodeid);
        Integer fsfcjdpzhq = oaSysFlowNode.getFsfcjdpzhq(); //是否从节点配置获取待办人
        String fblbmlx = oaSysFlowNode.getFblbmlx(); //办理部门类型
        String fblbmid = oaSysFlowNode.getFblbmid(); //办理部门id

        String fblgwid = oaSysFlowNode.getFblgwid(); //办理岗位id

        String fblrid = oaSysFlowNode.getFblrid(); //办理人id
        Integer fsfzdblr = oaSysFlowNode.getFsfzdblr(); //是否指定办理人
        Integer fsfzddlr= oaSysFlowNode.getFsfzddlr(); //是否指定登陆人为办理人
        Map map = new HashMap();
        //是否从节点配置获取待办人：0是 / 1否  为0则读取当前节点配置的环节办理人
        if (fsfcjdpzhq.equals(OaFlowNodeConstant.SFZD_YES)){
            //如果指定办理人 直接返回指定人
            if (fsfzdblr.equals(OaFlowNodeConstant.SFZD_YES)){
                if (StringUtils.isBlank(fblrid)){
                    throw new BusinessException("查询不到指定办理人");
                }
                String dbrName = oaFlowNodeDbrService.getDbrNameById(fblrid);
                map.put("dbr",dbrName);
                map.put("dbrId",fblrid);
                return map;
            }
            //如果指定当前登陆人 则返回当前登录用户
            if (fsfzddlr.equals(OaFlowNodeConstant.SFZD_YES)){
                String dbrid = currentUser.getId();
                String dbrname = currentUser.getName();
                map.put("dbr",dbrname);
                map.put("dbrId",dbrid);
                return map;
            }
            Map dbrByBmGw = getDbrByBmGw(fblbmid, fblgwid);
            //如果办理部门类型为 指定 则待办人 进入 根据部门和岗位判断
            if (fblbmlx.equals(OaFlowNodeConstant.BLJD_BLBM_ZD)){
                return dbrByBmGw;
                //在判断 办理部门类型为 不指定 则 待办人 根据 办理岗位id 来 判断
            }else if(fblbmlx.equals(OaFlowNodeConstant.BLJD_BLBM_BZD)){
                //否则根据办理部门id返回待办人
                return dbrByBmGw;
            }else if (fblbmlx.equals(OaFlowNodeConstant.BLJD_BLBM_DQBM) && StringUtils.isNotBlank(jobId)){
                //在这里写 如果 为当前部门 传入 业务id 根据 jobid 拿到所有信息
                //通过jobId 拿到nowNodeId
                OaJobEntity oaJobEntity = spcySqsxJobService.getById(jobId);
                String fnodeid = oaJobEntity.getFnodeid(); //获取当前节点id
                String fpid = oaJobEntity.getFpid();
                OaSysFlowNode flowNodeServiceById = sysFlowNodeService.getById(fnodeid);
                String flcmbid = flowNodeServiceById.getFlcmbid(); //通过流程模板id 可以获取流程节点的第一个环节
                List<OaSysFlowNode> firstNode = sysFlowNodeService.getFirstNode(flcmbid);
                String firstNodeId = firstNode.get(0).getId();//获取第一个流程节点的id
                //通过流程节点id 和jobid 对比 获取第一环节办理人姓名和id
                List<OaJobEntity> list = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>().eq(OaJobEntity::getFpid, fpid)
                        .eq(OaJobEntity::getFnodeid, firstNodeId));
                String fdbrid = list.get(0).getFdbrid();

                /** 2024-02-24 获取用户主部门id */
//                String orgId = ycSysUserService.getById(fdbrid).getOrgId();
                String orgId = ycSysUserService.getUserZbmByUserId(fdbrid);
                Map ByBmGw = getDbrByBmGw(orgId, fblgwid);
                return ByBmGw;
            }else if (fblbmlx.equals(OaFlowNodeConstant.BLJD_BLBM_DQBM)){
                return dbrByBmGw;
            }
        }else {
            map.put("dbr", "");
            map.put("dbrId", "");
            return map;
        }
        return map;
    }

    //根据办理部门id 和 办理岗位id 判断返回待办人
    public Map  getDbrByBmGw(String fblbmid,String fblgwid){
        Map map = new HashMap();
        String dbr="";
        String dbrid="";
        //null null  办理部门id和办理岗位id都为空 直接返回为空
        if (StringUtils.isBlank(fblbmid) && StringUtils.isBlank(fblgwid)){
            map.put("dbr",dbr);
            map.put("dbrId",dbrid);
            return map;
        }
        //null not  办理部门id为空 办理岗位id不为空  返回当前办理岗位的所有人
        if (StringUtils.isBlank(fblbmid) && StringUtils.isNotBlank(fblgwid)){
            //
            return oaFlowNodeDbrService.getDbrByGwid(fblgwid);
        }
        //not null 办理部门id不为空 办理岗位id为空  返回当前部门id的所有人
        if (StringUtils.isNotBlank(fblbmid) && StringUtils.isBlank(fblgwid)){
            return oaFlowNodeDbrService.getDbrByBmid(fblbmid);
        }
        // not not 办理部门id 和办理岗位id 都不为空 则返回当前部门下 当前办理岗位的用户
        if (StringUtils.isNotBlank(fblbmid) && StringUtils.isNotBlank(fblgwid)){
            //先判断办理岗位id 是不是分管领导
            List<OaSysJob> oaSysJobs = sysJobService.list(new LambdaQueryWrapper<OaSysJob>().eq(OaSysJob::getId, fblgwid));
            String jobName = oaSysJobs.get(0).getJobName();
            if (jobName.equals(OaFlowNodeConstant.ROLE_NAME_FGLD)){
                return oaFlowNodeDbrService.getKsFgldByDeptName(fblbmid);
            }else {
                return oaFlowNodeDbrService.getdbrByDeptName(fblbmid, fblgwid);
            }
        }
        map.put("dbr",dbr);
        map.put("dbrId",dbrid);
        return map;
    }



    /**
     *  提交任务
     * @param lcmbCode 流程模板编码
     * @param pid 主业务id
     * @param jobId 流程id
     * @param opinion 意见
     * @param nextNodeId 下一节点id
     * @param nextNodeDbrIds 下一节点待办人
     * @param isOverCurrentJob 是否办结 创建
     * @return
     */
    public Result passJob(String lcmbCode,String pid, String jobId, String opinion,String nextNodeId,String nextNodeDbrIds,boolean isOverCurrentJob){

        // 获得当前待办任务，并做校验
        OaJobEntity job= spcySqsxJobService.getById(jobId);
        if (job==null){
            return Result.error("查不到id为【"+jobId+"】的待办任务");
        }

        //获取办理人，并做办理人的校验，如果当前登录人不是待办人之一，拒绝办理
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        if (currentUser == null){
            return Result.error("请先登录");
        }
        if(isOverCurrentJob){
            //办理掉当前环节
            Result result = doJob(jobId,opinion);
            //在这里判断 是否是最后一个节点 如果是返回一个新的空对象
            boolean endNode = sysFlowNodeService.endNode(job.getFnodeid());
            if (endNode){
                OaJobEntity job1 = new OaJobEntity();
                return  Result.ok(job1);
            }

            job = (OaJobEntity) result.getResult();
            //生成下一环节的待办
            if(result.isSuccess()){
//                job = (SpcySqsxJob) result.getResult();

                if(job.getFblzt().equals(OaCommonFlowConstant.BLZT_YB)){
                    //创建下一环节任务
                    Result result1= createJob(lcmbCode,pid,nextNodeDbrIds,null,job,nextNodeId,currentUser);
                    if (!result1.isSuccess()){
                        return Result.error(result1.getMessage());
                    }else {
                        // 3-16 返回新增的流程任务
                        return Result.ok(result1.getResult());
                    }
                }
                // 3-16 返回当前流程任务
                return Result.ok(job);
            }else{
                return Result.error(result.getMessage());
            }
        }else{

            //创建下一环节任务
            Result result1= createJob(lcmbCode,pid,nextNodeDbrIds,null,job,nextNodeId,currentUser);
            if (!result1.isSuccess()){
                return Result.error(result1.getMessage());
            }else {
                // 3-16 返回新增的流程任务
                return Result.ok(result1.getResult());
            }
        }
    }
    /**
     * 办理环节
     *
     * @param job         当前流程任务
     * @param currentUser 当前用户
     * @param opinion     意见
     * @param returnNode  退回环节
     */
    private Result doJob(OaJobEntity job, CurrentUserVo currentUser, String opinion, String returnNode) {
        String blrId = "";
        String blr = "";
        String blbm = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
            blbm = currentUser.getOrgName();
        }
        if (job == null) {
            return Result.error("当前流程任务不存在，请重试");
        }
//        if(CommonFlowConstant.BLZT_YB.equals(job.getFblzt())){
//            return Result.error("当前任务已提交");
//        }
        if (StringUtils.isBlank(job.getFdbrid())) {
            return Result.error("当前任务未指定办理人");
        }
//        if(!job.getFdbrid().contains(blrId)){
//            return Result.error("当前登录用户无此任务的办理权限");
//        }
        // 办理方式 竞争办理 、多人线性办理 、多人并行办理
        String blfs = job.getFblfs();
        if (StringUtils.isBlank(blfs) || blfs.equals(OaCommonFlowConstant.BLFS_DRJJ)) {
            job.setFblr(blr);
            job.setFblsj(new Date());
            job.setFblyj(opinion);
            job.setFblzt(OaCommonFlowConstant.BLZT_YB);
            if (StringUtils.isBlank(returnNode)) {
                job.setFbllx(OaCommonFlowConstant.BLLX_BL);
            } else {
                job.setFbllx(returnNode);
            }
            job.setFblbm(blbm);

            // 审评查验流程 计算 办理天数、是否超时
            /*if (StringUtils.isNotBlank(job.getFlcmc()) && job.getFlcmc().contains(YpscFlowConstant.LCMC_LIKE_SPCYLC)) {
                job.setFsyts(flowJobBlsxService.jsTwoDateBetweenDays(job.getFksyts(),job.getFpid(),job.getFfssj(), job.getFblsj(), job.getFztkssj(),job.getFztjssj())); // 使用天数
                job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时
            }*/

            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        } else if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX) || blfs.equals(OaCommonFlowConstant.BLFS_DRBX)) {
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId = "";
            String nextBlr = "";
            if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX)) {
                String ydbrIds[] = job.getFydbrid().split(",");
                String ydbrs[] = job.getFydbr().split(",");
                for (int i = 0; i < ydbrIds.length; i++) {
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (dbrId.equals(blrId)) {
                        if (i + 1 < ydbrIds.length) {
                            nextBlrId = ydbrIds[i + 1];
                            nextBlr = ydbrs[i + 1];
                            break;
                        }
                    }
                }
            } else {
                String dbrIds[] = job.getFdbrid().split(",");
                String dbrs[] = job.getFdbr().split(",");
                for (int i = 0; i < dbrIds.length; i++) {
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (!dbrId.equals(blrId)) {
                        nextBlrId = nextBlrId + (StringUtils.isBlank(nextBlrId) ? "" : ",") + dbrId;
                        nextBlr = nextBlr + (StringUtils.isBlank(nextBlr) ? "" : ",") + dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            job.setFblr(blr);
            job.setFblsj(new Date());
            String blyj = (job.getFblyj() == null ? "" : job.getFblyj()) + (StringUtils.isBlank(job.getFblyj()) ? "" : "@@") + DateConversionUtils.DateToString(new Date()) + "|" + blr + "|" + opinion;
            job.setFblyj(blyj);
            if (StringUtils.isBlank(nextBlrId)) {
                job.setFblzt(OaCommonFlowConstant.BLZT_YB);
                if (StringUtils.isBlank(returnNode)) {
                    job.setFbllx(OaCommonFlowConstant.BLLX_BL);
                } else {
                    job.setFbllx(returnNode);
                }
                job.setFblbm(blbm);
            } else {
                job.setFblzt(OaCommonFlowConstant.BLZT_DB);
                job.setFdbrid(nextBlrId);
                job.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }
        return Result.error("待办任务未指定办理方式");
    }

    /**
     * @param job
     * @Description 办结当前环节
     */
    public Result doJob(String job, String opinion) {
        OaJobEntity byId = spcySqsxJobService.getById(job);
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        String blrId = "";
        String blr = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
        }
        if (job == null) {
            return Result.error("当前流程任务不存在，请重试");
        }
        if (OaCommonFlowConstant.BLZT_YB.equals(byId.getFblzt())) {
            return Result.error("当前任务已提交");
        }
//        if(StringUtils.isBlank(job.getFdbrid())){
//            return Result.error("当前任务未指定办理人");
//        }
        if (!byId.getFdbrid().contains(blrId)) {
            return Result.error("当前登录用户无此任务的办理权限");
        }
        // 办理方式  、多人竞争办理
        String blfs = byId.getFblfs();
        if (StringUtils.isBlank(blfs) || blfs.equals(OaCommonFlowConstant.BLFS_DRJJ)) {
            byId.setFblr(blr);
            byId.setFblsj(new Date());
            byId.setFblyj(opinion);
            byId.setFblzt(OaCommonFlowConstant.BLZT_YB);
            spcySqsxJobService.updateById(byId);
            return Result.ok(byId);
        } else if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX) || blfs.equals(OaCommonFlowConstant.BLFS_DRBX)) {
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId = "";
            String nextBlr = "";
            if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX)) {
                String ydbrIds[] = byId.getFydbrid().split(",");
                String ydbrs[] = byId.getFydbr().split(",");
                for (int i = 0; i < ydbrIds.length; i++) {
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (dbrId.equals(blrId)) {
                        if (i + 1 < ydbrIds.length) {
                            nextBlrId = ydbrIds[i + 1];
                            nextBlr = ydbrs[i + 1];
                            break;
                        }
                    }
                }
            } else {
                String dbrIds[] = byId.getFdbrid().split(",");
                String dbrs[] = byId.getFdbr().split(",");
                for (int i = 0; i < dbrIds.length; i++) {
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (!dbrId.equals(blrId)) {
                        nextBlrId = nextBlrId + (StringUtils.isBlank(nextBlrId) ? "" : ",") + dbrId;
                        nextBlr = nextBlr + (StringUtils.isBlank(nextBlr) ? "" : ",") + dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            byId.setFblr(blr);
            byId.setFblsj(new Date());
            String blyj = (byId.getFblyj() == null ? "" : byId.getFblyj()) + (StringUtils.isBlank(byId.getFblyj()) ? "" : "@@") + DateConversionUtils.DateToString(new Date()) + "|" + blr + "|" + opinion;
            byId.setFblyj(blyj);
            if (StringUtils.isBlank(nextBlrId)) {
                byId.setFblzt(OaCommonFlowConstant.BLZT_YB);
            } else {
                byId.setFblzt(OaCommonFlowConstant.BLZT_DB);
                byId.setFdbrid(nextBlrId);
                byId.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(byId);
            return Result.ok(byId);
        }
        return Result.error("待办任务未指定办理方式");
    }

    /***
     * 批量销假 使用 办结
     */
    public Result doJobs(String job, String opinion) {
        OaJobEntity byId = spcySqsxJobService.getById(job);
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        String blrId = "";
        String blr = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
        }
        if (job == null) {
            return Result.error("当前流程任务不存在，请重试");
        }
        if (OaCommonFlowConstant.BLZT_YB.equals(byId.getFblzt())) {
            return Result.error("当前任务已提交");
        }
//        if(StringUtils.isBlank(job.getFdbrid())){
//            return Result.error("当前任务未指定办理人");
//        }
//        if (!byId.getFdbrid().contains(blrId)) {
//            return Result.error("当前登录用户无此任务的办理权限");
//        }
        // 办理方式  、多人竞争办理
        String blfs = byId.getFblfs();
        if (StringUtils.isBlank(blfs) || blfs.equals(OaCommonFlowConstant.BLFS_DRJJ)) {
            byId.setFblr(blr);
            byId.setFblsj(new Date());
            byId.setFblyj(opinion);
            byId.setFblzt(OaCommonFlowConstant.BLZT_YB);
            spcySqsxJobService.updateById(byId);
            return Result.ok(job);
        } else if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX) || blfs.equals(OaCommonFlowConstant.BLFS_DRBX)) {
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId = "";
            String nextBlr = "";
            if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX)) {
                String ydbrIds[] = byId.getFydbrid().split(",");
                String ydbrs[] = byId.getFydbr().split(",");
                for (int i = 0; i < ydbrIds.length; i++) {
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (dbrId.equals(blrId)) {
                        if (i + 1 < ydbrIds.length) {
                            nextBlrId = ydbrIds[i + 1];
                            nextBlr = ydbrs[i + 1];
                            break;
                        }
                    }
                }
            } else {
                String dbrIds[] = byId.getFdbrid().split(",");
                String dbrs[] = byId.getFdbr().split(",");
                for (int i = 0; i < dbrIds.length; i++) {
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (!dbrId.equals(blrId)) {
                        nextBlrId = nextBlrId + (StringUtils.isBlank(nextBlrId) ? "" : ",") + dbrId;
                        nextBlr = nextBlr + (StringUtils.isBlank(nextBlr) ? "" : ",") + dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            byId.setFblr(blr);
            byId.setFblsj(new Date());
            String blyj = (byId.getFblyj() == null ? "" : byId.getFblyj()) + (StringUtils.isBlank(byId.getFblyj()) ? "" : "@@") + DateConversionUtils.DateToString(new Date()) + "|" + blr + "|" + opinion;
            byId.setFblyj(blyj);
            if (StringUtils.isBlank(nextBlrId)) {
                byId.setFblzt(OaCommonFlowConstant.BLZT_YB);
            } else {
                byId.setFblzt(OaCommonFlowConstant.BLZT_DB);
                byId.setFdbrid(nextBlrId);
                byId.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(byId);
            return Result.ok(byId);
        }
        return Result.error("待办任务未指定办理方式");
    }


    /**
     * 查询流程当前环节-上一环节
     * * @param jobid 流程任务id
     * * @param isZdhj 是否指定环节
     * * @return
     */
    public List<Map<String, String>> getCurrentJobPrevious(String jobid, boolean isZdhj) {
        if (StringUtils.isBlank(jobid)) {
            throw new BusinessException("流程任务参数为空！");
        }

        OaJobEntity currentJob = spcySqsxJobService.getById(jobid);
        if (currentJob == null) {
            throw new BusinessException("当前流程任务不存在！");
        }


        String fpid = currentJob.getFpid(); // 关联业务id
        String flcmc = currentJob.getFlcmc(); // 所属流程名称
        String fnodeid = currentJob.getFnodeid(); //当前节点名称


        List<Map<String, String>> ybNodeList = new ArrayList<>(); // 退回环节数组
        String previousNode = this.getPreviousNodeBynodeId(fnodeid); // 上一环节

        // 指定环节
        if (isZdhj) {
            List<OaJobEntity> preJobList = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>()
                    .eq(OaJobEntity::getFpid, fpid)
                    .eq(OaJobEntity::getFblzt, OaCommonFlowConstant.BLZT_YB)
                    .eq(OaJobEntity::getFlcmc, flcmc)
                    .orderByAsc(OaJobEntity::getFfssj));
            if (CollectionUtils.isNotEmpty(preJobList)) {
                for (OaJobEntity job : preJobList) {

                    // 判断是否存在一样的环节名称，存在跳出当次循环
                    boolean isExistNode = false;
                    if (CollectionUtils.isNotEmpty(ybNodeList)) {
                        for (Map<String, String> disMap : ybNodeList) {
                            if (disMap.get("fhjmc").equals(job.getFhjmc())) {
                                isExistNode = true;
                                break;
                            }
                        }
                    }
                    if (isExistNode) {
                        continue;
                    }
                    Map<String, String> map = new HashMap<>();
                    map.put("id", job.getId());
                    map.put("fhjmc", job.getFhjmc());
                    ybNodeList.add(map);
                }
            }
        } else {
            // 查询上一环节是否存在
            List<OaJobEntity> preJobList = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>()
                    .eq(OaJobEntity::getFpid, fpid)
                    .eq(OaJobEntity::getFhjmc, previousNode)
                    .eq(OaJobEntity::getFblzt, OaCommonFlowConstant.BLZT_YB)
                    .eq(OaJobEntity::getFlcmc, flcmc)
                    .orderByDesc(OaJobEntity::getFfssj));

            if (CollectionUtils.isNotEmpty(preJobList)) {
                Map<String, String> map = new HashMap<>();
                map.put("id", preJobList.get(0).getId());
                map.put("fhjmc", preJobList.get(0).getFhjmc());
                ybNodeList.add(map);
            }
        }
        return ybNodeList;
    }


    /**
     * 退回流程 - 指定环节
     */
    public void returnZdJob(OaReturnVo oaReturnVo) {
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        if (currentUser == null) {
            throw new BusinessException("登录已失效，请重新登录！");
        }

        if (StringUtils.isBlank(oaReturnVo.getJobid())) {
            throw new BusinessException("流程任务参数为空！");
        }

        if (StringUtils.isBlank(oaReturnVo.getOpinion())) {
            throw new BusinessException("请填写退回意见！");
        }

        if (StringUtils.isBlank(oaReturnVo.getShjid())) {
            throw new BusinessException("请选择退回环节！");
        }

        // 当前环节
        OaJobEntity currentJob = spcySqsxJobService.getById(oaReturnVo.getJobid());
        if (currentJob == null) {
            throw new BusinessException("当前流程任务不存在！");
        }

        String sqsxid = currentJob.getFpid();
        String oldfhjmc = currentJob.getFhjmc();


        // 上一环节
        OaJobEntity previousJob = spcySqsxJobService.getById(oaReturnVo.getShjid());
        if (currentJob == null) {
            throw new BusinessException("当前流程任务不存在！");
        }
        String previousNode = previousJob.getFhjmc();

        String bllx = "[" + oldfhjmc + "]" + OaCommonFlowConstant.BLLX_TH + "[" + previousNode + "]";
        Result result = this.doJob(currentJob, currentUser, oaReturnVo.getOpinion(), bllx);
        if (!result.isSuccess()) {
            throw new BusinessException(result.getMessage());
        }

        /**
         * 创建退回环节流程任务
         */
        OaJobEntity newPreviousJob = new OaJobEntity();
        BeanUtil.copyProperties(previousJob, newPreviousJob);
        newPreviousJob.setId(GetUuIdUtils.NotReplaceUuId());

        if (StringUtils.isBlank(newPreviousJob.getFpid())) {
            newPreviousJob.setFpid(sqsxid);
        }


        newPreviousJob.setFblzt(OaCommonFlowConstant.BLZT_TH);
        newPreviousJob.setFblyj("");
        newPreviousJob.setFblr("");
        newPreviousJob.setFblsj(null);
        newPreviousJob.setFblbm("");
        newPreviousJob.setFthyj(oaReturnVo.getOpinion());
        newPreviousJob.setFlcmc(OaFlowConstant.BXD_TSSXSQ_NAME);
        newPreviousJob.setFbllx("");
        newPreviousJob.setFfssj(new Date());
        newPreviousJob.setFfsrid(currentUser.getId());
        newPreviousJob.setFfsrmc(currentUser.getName());
        newPreviousJob.setFsfkch("");
        spcySqsxJobService.save(newPreviousJob);
        //处理主表数据
        OaSpcyJcyFybxdtssxsq fybxdtssxsq = spcyFybxdtssxsqService.getById(sqsxid);
        if (previousNode.equals(OaFlowConstant.TSSXSQ_SQ)) {

        }
    }

    /**
     * 获取上一环节-通过当前流程节点id
     *
     * @param nodeId 当前节点id
     * @return
     */
    private String getPreviousNodeBynodeId(String nodeId) {
        String preNode = "";
        List<OaSysFlowNode> previousNode = sysFlowNodeService.getPreviousNode(nodeId);
        preNode=  previousNode.get(0).getFjdmc();
        return preNode;
    }

    public String getms(String oaid,String sqsxid,String lcbm) throws Exception {
        NkRsCcsp ccsps = nkRsCcspService.getById(oaid);
        if (lcbm.equals(OaFlowConstant.NK_CCSP) && ccsps!= null){
            //检查天数/天数
            int jcts = 0;
            //开始时间
            String kssj = "";
            //结束时间
            String jssj = "";
            String bxnrms = "";
            String bxsjms = "";

            if (lcbm.equals(OaFlowConstant.NK_CCSP)){
                NkRsCcsp ccsp = nkRsCcspService.getById(sqsxid);
                bxnrms = ccsp.getFccsy();

                //天数
                String fccksrq = ccsp.getFccksrq();
                String fccjsrq = ccsp.getFccjsrq();
                kssj = fccksrq;
                jssj = fccjsrq;

                long day = DateConversionUtils.dateDiffWithDay(fccksrq, fccjsrq);
                jcts = (int) day;
                //报销时间描述
                bxsjms = fccksrq + "至" + fccjsrq + "共" + jcts + "天";
            }
            String ms =  bxnrms +  bxsjms;
            return ms;
        }else {

            OaSpcyJcyFybxdtssxsq byId = spcyFybxdtssxsqService.getById(oaid);
            if (StringUtils.isNotBlank(byId.getFewfybxsm())){
                return byId.getFewfybxsm();
            }else {
                return byId.getFsqlx();
            }




        }

    }






}


